package com.letv.whatslive.redis;

import com.letv.whatslive.common.utils.ObjectUtils;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;

/**
 * Created by liyulin on 2016/3/1.
 */
@Repository
public class KedisDAO {

    private static final String KEDIS_TIMESTAMP = "kedis_timestamp";
    private static final String COLON = ",";

    @Resource
    private JedisDAO jedisDAO;

    /**
     * 从缓存中取数据<br />
     * 返回结果==null，读取DB，并调用{@link KedisDAO#setDataToCache}更新缓存
     *
     * @param key
     * @return
     */
    public String getDataFromCache(String key) {
        String result = jedisDAO.getJedisReadTemplate().get(key);
        // if get nothing from cache, then update cache from db
        if (result == null) {
            return null;
        }

        String time = jedisDAO.getJedisReadTemplate().hget(KEDIS_TIMESTAMP, key);
        // if can not get time, the cache data is old, then update cache from db
        if (time == null) {
            return null;
        }

        String[] times = time.split(COLON);
        // if times not 3, then the cache time is incorrect, then update cache from db
        if (times.length < 3) {
            return null;
        }

        long now = System.currentTimeMillis() / 1000;
        long initTime = ObjectUtils.toLong(times[0], 0L);
        long expireTime = ObjectUtils.toLong(times[1], 0L);
        long appendTime = ObjectUtils.toLong(times[2], 0L);
        if (initTime + expireTime > now) {
            return result;
        }

        initTime = now - expireTime + appendTime;
        time = initTime + COLON + expireTime + COLON + appendTime;
        // the business-logic timestamp for another appendTime seconds to avoid other threads query db
        jedisDAO.getJedisWriteTemplate().hset(KEDIS_TIMESTAMP, key, time);
        // update the cache from db for the business-logic timestamp is already expired
        return null;
    }

    /**
     * 更新cache
     *
     * @param key
     * @param value
     * @param cacheExpireTime cache过期时间
     * @param expireTime      业务过期时间
     * @param appendTime      业务延期时间
     */
    public void setDataToCache(String key, String value, int cacheExpireTime, int expireTime, int appendTime) {
        long now = System.currentTimeMillis() / 1000;
        // save the real data to cache
        jedisDAO.getJedisWriteTemplate().setex(key, value, cacheExpireTime);
        String times = now + COLON + expireTime + COLON + appendTime;
        // save business-logic timestamp to cache
        jedisDAO.getJedisWriteTemplate().hset(KEDIS_TIMESTAMP, key, times);
    }

    /**
     * 更新cache
     *
     * @param key
     * @param value
     * @param cacheExpireTime cache过期时间
     * @param appendTime      业务延期时间
     */
    public void setDataToCache(String key, String value, int cacheExpireTime, int appendTime) {
        long now = System.currentTimeMillis() / 1000;
        int expireTime = cacheExpireTime - appendTime;
        // save the real data to cache
        jedisDAO.getJedisWriteTemplate().setex(key, value, cacheExpireTime);
        String times = now + COLON + expireTime + COLON + appendTime;
        // save business-logic timestamp to cache
        jedisDAO.getJedisWriteTemplate().hset(KEDIS_TIMESTAMP, key, times);
    }

}
